package org.ttitfly.workflow.handler.adapter;

import org.ttitfly.workflow.Session;
import org.ttitfly.workflow.SessionHolder;
import org.ttitfly.workflow.handler.Handler;
import org.ttitfly.workflow.handler.HandlerInvocation;
import org.ttitfly.workflow.handler.ReflectMethodInvoker;


/**
 * 反射方法适配，本类将反射Method对象适配成Handler对象。
 * 
 * @author 潘海春
 * @version 2009-9-3
 */
public class RefletctMethodHandlerAdapter implements Handler {

	/**
	 * 目标调用对象
	 */
	private ReflectMethodInvoker invoker;

	/**
	 * 对应参数名称，执行时将根据参数名称从请求数据里面获取值，因此设计时应该将方法的参数名称与请求参数名称一致，否则可能出现参数为null的情况
	 */
	protected String[] argNames;

	/**
	 * 构造函数
	 * 
	 * @param component
	 * @param methodName
	 * @param argNames
	 */
	public RefletctMethodHandlerAdapter(Object component, String methodName, String... argNames) {
		this(new ReflectMethodInvoker(component, methodName, argNames), argNames);
	}

	/**
	 * 构造函数
	 * 
	 * @param method
	 * @param component
	 * @param argNames
	 */
	public RefletctMethodHandlerAdapter(ReflectMethodInvoker invoker, String... argNames) {
		if (invoker == null) {
			throw new IllegalArgumentException("argument invoker can not be null!");
		}
		this.invoker = invoker;
		this.argNames = argNames;
	}

	@Override
	public Object handle(HandlerInvocation invocation) throws Exception {
		Session session = SessionHolder.currentSession();
		Object[] args = new Object[0];
		if (argNames != null && argNames.length > 0) {
			args = new Object[argNames.length];
			for (int i = 0; i < argNames.length; i++) {
				args[i] = session.getVariable(argNames[i]);
			}
		}
		Object retVal = invoker.invoke(args);
		Object retVal2 = invocation.proceed();
		// 如果方法有返回值，则使用该返回值返回，如果此时后续handler链有返回值的话将被忽略，
		// 如果确实需要使用前面处理程序的返回值的话，请设置好handler的顺序
		// 默认情况返回后续handler的返回值
		return retVal != null ? retVal : retVal2;
	}

}
